﻿
//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////
#pragma once

#include "OwnerPtr.h"
#include "CommandBase.h"
#include "GraphicsNodeId.h"
#include "IGraphicsElementShape.h"
#include "IFieldProxy.h"

/// 本文件是界面实现的辅助类，不包含GDMP API的演示内容

namespace gcmp
{
    enum class FilterMode;
    enum class TextPrimitiveType;
    enum class GraphicsRenderLayer;
    enum class PointDisplayShapeType;
    enum class GraphicsNodeVisibility;
    enum class AnchorAlignmentType;
    enum class HorizontalAlignmentType;
    enum class VerticalAlignmentType;
    enum class HorizontalAnchorPointType;
    enum class VerticalAnchorPointType;

    class IGraphicsNode;
    class IGraphicsText;
    class IGraphicsPoint;
    class IGraphicsPlane;
    class IGraphicsCurve3d;
    class IGraphicsPicture;
    class IGraphicsGisLayer;
    class IGraphicsRichText;
    class IGraphicsBRepFace;
    class IGraphicsBRepBody;
    class IGraphicsMeshBody;
    class IGraphicsBRepEdge;
    class IGraphicsZoomFree;
    class IGraphicsNodeGroup;
    class IGraphicsPolyCurve;
    class IGraphicsPolyCurve3d;
    class IGraphicsNodeReference;
    class IGraphicsElementShapeReference;
    class ILinkElementModelShapeReference;
    class IGraphicsOtherDocumentElementShapeReference;
}

namespace Sample
{
    class IParameterDisplay;
    class CmdObjectBrowser;

    class ObjectWrapper
    {
    public:
        virtual ParametersArrayDict& GetParameters() = 0;
        virtual std::wstring GetObjectName() = 0;
    };

    /// GRep探针浏览器中GNode数据的包装类
    class IGraphicsNode_Wrapper : public ObjectWrapper
    {
    public:
        IGraphicsNode_Wrapper(gcmp::ElementId id, gcmp::IGraphicsNode* pGraphicsNode, bool isReadOnly, IGraphicsNode_Wrapper* pParent);

        virtual ParametersArrayDict& GetParameters() override;
        virtual std::wstring GetObjectName() override { return m_className; };

        IGraphicsNode_Wrapper* GetParent() { return m_pParent; }
        IGraphicsNode_Wrapper* GetRootParent();
        std::vector<gcmp::OwnerPtr<IGraphicsNode_Wrapper>>& GetChildren();
        gcmp::IGraphicsNodeReference& GetGNodeReference();

        gcmp::IGraphicsNode* GetGraphicsNode() { return m_pGraphicsNode; };
        gcmp::ElementId GetElementId() { return m_elementId; }
        void SetGraphicsNodeIdPath(std::vector<gcmp::GraphicsNodeId> gNodeIdPath);

        void CacheGRep(gcmp::OwnerPtr<gcmp::IGraphicsElementShape> opGRep) { m_opGRep = TransferOwnership(opGRep); };
        gcmp::OwnerPtr<gcmp::IGraphicsElementShape> GetCachedGRep() { return TransferOwnership(m_opGRep); }

        void RunSetFieldFuncs();

        bool IsReadOnly() { return m_isReadOnly; }
    private:
        void VisitGNode();
        void VisitGBody(gcmp::IGraphicsBRepBody* pGBodyNode);
        void VisitGCurve(gcmp::IGraphicsCurve3d* pGCurve);
        void VisitGDocReference(gcmp::IGraphicsOtherDocumentElementShapeReference* pDocNode);
        void VisitGEdge(gcmp::IGraphicsBRepEdge* pGEdgeNode);
        void VisitGFace(gcmp::IGraphicsBRepFace* pGFaceNode);
        void VisitGGroup(gcmp::IGraphicsNodeGroup* pGroup);
        void VisitGISTile(gcmp::IGraphicsGisLayer* pGISTile);
        void VisitGInstance(gcmp::IGraphicsElementShapeReference* pInstanceNode);
        void VisitGLinkReference(gcmp::ILinkElementModelShapeReference* pLinkElementNode);
        void VisitGMeshBody(gcmp::IGraphicsMeshBody* pGBodyNode);
        void VisitGPicture(gcmp::IGraphicsPicture* pPictureNode);
        void VisitGPlane(gcmp::IGraphicsPlane* pGPlaneNode);
        void VisitGPoint(gcmp::IGraphicsPoint* pGPointNode);
        void VisitGPolyCurve(gcmp::IGraphicsPolyCurve* pPolyCurve);
        void VisitGPolyCurve3d(gcmp::IGraphicsPolyCurve3d* pPolyCurve3d);
        void VisitGRep(gcmp::IGraphicsElementShape* pGRepNode);
        void VisitGText(gcmp::IGraphicsText* pGTextNode);
        void VisitRichText(gcmp::IGraphicsRichText* pRichTextNode);
        void VisitGZoomfree(gcmp::IGraphicsZoomFree* pGZoomfree);

        friend class GNodeUtility;
    private:
        gcmp::IGraphicsNode* m_pGraphicsNode;
        std::wstring m_className;
        ParametersArrayDict m_parameters;
        gcmp::ElementId m_elementId;
        gcmp::OwnerPtr<gcmp::IGraphicsNodeReference> m_opGNodeReference;

        IGraphicsNode_Wrapper* m_pParent;
        std::vector<gcmp::OwnerPtr<IGraphicsNode_Wrapper>> m_children;
        std::vector<gcmp::GraphicsNodeId> m_graphicsNodeIdPath;

        gcmp::OwnerPtr<gcmp::IGraphicsElementShape> m_opGRep;

        static std::map<gcmp::FilterMode, std::wstring> s_filterModeMap;
        static std::map<gcmp::GraphicsRenderLayer, std::wstring> s_gRenderLayerMap;
        static std::map<gcmp::GraphicsNodeVisibility, std::wstring> s_gNodeVisMap;
        static std::map<gcmp::PointDisplayShapeType, std::wstring> s_pointShapeTypeMap;
        static std::map<gcmp::TextPrimitiveType, std::wstring> s_textPrimitiveTypeMap;
        static std::map<gcmp::AnchorAlignmentType, std::wstring> s_textAnchorAlignmentTypeMap;
        static std::map<gcmp::HorizontalAlignmentType, std::wstring> s_HorizontalAlignmentTypeMap;
        static std::map<gcmp::VerticalAlignmentType, std::wstring> s_VerticalAlignmentTypeMap;
        static std::map<gcmp::HorizontalAnchorPointType, std::wstring> s_HorizontalAnchorPointTypeMap;
        static std::map<gcmp::VerticalAnchorPointType, std::wstring> s_VerticalAnchorPointTypeMap;

        static std::vector<std::wstring> s_filterModeList;
        static std::vector<std::wstring> s_gRenderLayerList;
        static std::vector<std::wstring> s_gNodeVisList;
        static std::vector<std::wstring> s_pointShapeTypeList;
        static std::vector<std::wstring> s_textPrimitiveTypeList;
        static std::vector<std::wstring> s_textAnchorAlignmentTypeList;
        static std::vector<std::wstring> s_HorizontalAlignmentTypeList;
        static std::vector<std::wstring> s_VerticalAlignmentTypeList;
        static std::vector<std::wstring> s_HorizontalAnchorPointTypeList;
        static std::vector<std::wstring> s_VerticalAnchorPointTypeList;

        template<typename enumType>
        static std::vector<std::wstring> mapToVector(std::map<enumType, std::wstring> map)
        {
            std::vector<std::wstring> result;
            for (auto& pair : map)
            {
                result.emplace_back(pair.second);
            }
            return result;
        }

        bool m_isReadOnly;

        gcmp::IGraphicsText* m_pGraphicsText;
        gcmp::IGraphicsPoint* m_pGraphicsPoint;
        gcmp::IGraphicsPlane* m_pGraphicsPlane;
        gcmp::IGraphicsCurve3d* m_pGraphicsCurve3d;
        gcmp::IGraphicsPicture* m_pGraphicsPicture;
        gcmp::IGraphicsGisLayer* m_pGraphicsGisLayer;
        gcmp::IGraphicsRichText* m_pGraphicsRichText;
        gcmp::IGraphicsBRepFace* m_pGraphicsBRepFace;
        gcmp::IGraphicsBRepBody* m_pGraphicsBRepBody;
        gcmp::IGraphicsMeshBody* m_pGraphicsMeshBody;
        gcmp::IGraphicsBRepEdge* m_pGraphicsBRepEdge;
        gcmp::IGraphicsZoomFree* m_pGraphicsZoomFree;
        gcmp::IGraphicsNodeGroup* m_pGraphicsNodeGroup;
        gcmp::IGraphicsPolyCurve* m_pGraphicsPolyCurve;
        gcmp::IGraphicsPolyCurve3d* m_pGraphicsPolyCurve3d;
        gcmp::IGraphicsElementShape* m_pGraphicsElementShape;
        gcmp::IGraphicsNodeReference* m_pGraphicsNodeReference;
        gcmp::IGraphicsElementShapeReference* m_pGraphicsElementShapeReference;
        gcmp::ILinkElementModelShapeReference* m_pLinkElementModelShapeReference;
        gcmp::IGraphicsOtherDocumentElementShapeReference* m_pGraphicsOtherDocumentElementShapeReference;
    };
}

